#pragma once
#include <iostream>
#include <map>
#include <tuple>
#include <string>
#include <time.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_statistics.h>
#include <gsl/gsl_cdf.h>

using namespace std;

typedef tuple<double, double, double, double> params;
typedef map<params, double> cache_data;
typedef map<int, cache_data> cache;

void display(gsl_vector* x);

gsl_vector* add(gsl_vector* a, gsl_vector* b);
gsl_vector* add(gsl_vector* a, double b);
gsl_vector* add(double a, gsl_vector* b);
gsl_vector* sub(gsl_vector* a, gsl_vector* b);
gsl_vector* sub(gsl_vector* a, double b);
gsl_vector* sub(double a, gsl_vector* b);

gsl_vector* I(gsl_vector* x);
double E(gsl_vector* x, gsl_vector* p);
gsl_vector* p_norm(gsl_vector* x, double mu, double sigma);
double relative_error(double m, double n);

gsl_vector* range(int begin, int end, int interval);